﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using SX.BaseService.Repository.Core;
using SX.BaseService.Repository.Entity;
using SX.Core;
using SX.Core.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace SX.BaseService.API
{
    /// <summary>
    /// 初始化权限数据
    /// </summary>
    public class ApplicationHelper:DbContext
    {
        private static List<SysPermissionEntity> list = new List<SysPermissionEntity>();

        public  ApplicationHelper()
        {
            RedisHelper.Initialization(new CSRedis.CSRedisClient(ConfigHelper.Get("RedisConnStr")));
        }
        /// <summary>
        /// 初始化菜单和权限
        /// </summary>
        /// <param name="_parse_type"></param>
        public async Task Init(List<Type> types)
        {
            try
            {
                int menuIndex = 0;
                int apiIndex = 0;
                //遍历所有类
                foreach (var type in types)
                {
                    string className = type.Name.ToLower();
                    if (!className.EndsWith("controller") || (className == "basecontroller")) continue;

                    //控制器名称
                    string strcontroller = type.Name.ToLower();
                    strcontroller = strcontroller.Replace("controller", "");
                    //控制器的Area
                    object[] attributesArea = type.GetCustomAttributes(typeof(AreaAttribute), true);
                    var areaStr = "";
                    if (attributesArea != null && attributesArea.Length == 1)
                    {
                        AreaAttribute area = attributesArea[0] as AreaAttribute;
                        areaStr = area.RouteValue.ToLower();
                    }
                    //描述信息
                    object[] desAttrbutes = type.GetCustomAttributes(typeof(DescriptionAttribute), true);
                    var desStr = "";
                    if (desAttrbutes != null && desAttrbutes.Length == 1)
                    {
                        DescriptionAttribute desc = desAttrbutes[0] as DescriptionAttribute;
                        desStr = desc.Description.ToLower();
                    }

                    //遍历所有方法
                    MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
                    //如果控制器下无方法
                    if (methods == null || methods.Count() <= 0) continue;

                    //如果有MenuAttribute 需要自动生成菜单
                    var menuId =string.Empty;
                    object[] menuAttrbutes = type.GetCustomAttributes(typeof(MenuAttribute), true);
                    if (menuAttrbutes != null&&menuAttrbutes.Length==1)
                    {
                        menuId = GuidHelper.NewSequentialGuid();
                        //菜单
                        list.Add(new SysPermissionEntity
                        {
                            Id =menuId,
                            Name = desStr,
                            Code = $"{areaStr}_{strcontroller}",
                            Path = $"/{areaStr}/{strcontroller}",
                            Icon = "menu-module",//默认菜单Icon
                            Sort = menuIndex,
                            Type = 0,//menu
                            CreateTime = DateTime.Now,
                            Enabled = 1,
                            Remarks = "自动生成",
                            ParentId="0"//设为0 表示是默认根节点

                        });
                        menuIndex++;
                    }
                    else
                    {
                        var old= Db.Queryable<SysPermissionEntity>().Where(x => x.Code.ToLower() == $"{areaStr}_{strcontroller}").Single();
                        if (old != null)
                        {
                            menuId = old.Id;
                        }
                       
                    }

                    //Aciton
                    foreach (var method in methods)//遍历方法
                    {
                        object[] allAttrbutes_Method = method.GetCustomAttributes(typeof(AllowAnonymousAttribute), true);
                        object[] commonAttrbutes_Method = method.GetCustomAttributes(typeof(CommonAttribute), true);
                        //如果是公开接口则不写入数据库
                        if ((allAttrbutes_Method != null&&allAttrbutes_Method.Length>0) || (commonAttrbutes_Method != null&&commonAttrbutes_Method.Length>0))
                        {
                            continue;
                        }
                        var desStr_Method = string.Empty;
                        object[] desAttrbutes_Method = method.GetCustomAttributes(typeof(DescriptionAttribute), true);
                        if (desAttrbutes_Method != null && desAttrbutes_Method.Length == 1)
                        {
                            DescriptionAttribute des = desAttrbutes_Method[0] as DescriptionAttribute;
                            desStr_Method = des.Description.ToLower().Trim();
                        }
                        var platform = 0;
                        if (menuId.IsNull())
                        {
                            platform = 1;
                        }
                        list.Add(new SysPermissionEntity
                        {
                            Id = GuidHelper.NewSequentialGuid(),
                            Name = desStr_Method,
                            Code = $"{areaStr}_{strcontroller}_{method.Name.ToLower()}",
                            Path = "",
                            Icon = "",//默认菜单Icon
                            Sort = apiIndex,
                            Type = 1,//action
                            CreateTime = DateTime.Now,
                            Enabled = 1,
                            Remarks = "自动生成",
                            ParentId=menuId,
                            Platform=platform
                        });
                        apiIndex++;
                    }
                }

                //从redis取到别的服务的权限数据
                var permission_Json= RedisHelper.Get("Permission:Init");
                if (permission_Json!=null)
                {
                    var list_other = JsonHelper.DeserializeObject<List<SysPermissionEntity>>(permission_Json);
                    list.AddRange(list_other);
                }
                
                //删除旧数据
                //Db.Ado.ExecuteCommand("DELETE FROM SysPermission WHERE CODE NOT IN (@CODE)",new { CODE = list.Select(X => X.Code).ToArray() });
                var oldList = Db.Queryable<SysPermissionEntity>().ToList();
                var x = Db.Storageable(list)
                   .SplitUpdate(it => oldList.Any(x=>x.Code==it.Item.Code))//数据库存在更新 根据Code
                   .SplitInsert(it => !oldList.Any(x => x.Code == it.Item.Code))//新增
                   .ToStorage();//将数据进行分组

                await x.BulkCopyAsync();
                await x.BulkUpdateAsync("Name");//这里可以指定更新列

                InitAdminPermission();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"初始化权限数据失败：{ex.Message}");
            }
        }


        //初始化超级管理员默认全部权限
        public void InitAdminPermission()
        {
            var roleid = Db.Ado.GetString("select top 1 id from sysrole where name='超级管理员'");

            var list_permission = Db.Queryable<SysPermissionEntity>().ToList();
            var list_role_permission = Db.Queryable<SysRolePermissionEntity>().ToList();
            var list_add = new List<SysRolePermissionEntity>();

            foreach (var item in list_permission)
            {
                if (list_role_permission.Any(a => a.RoleId == roleid && a.PermissionId == item.Id)) continue;
                var data = new SysRolePermissionEntity()
                {
                    RoleId = roleid,
                    PermissionId = item.Id
                };

                list_add.Add(data);
            }
            Db.Insertable<SysRolePermissionEntity>(list_add).ExecuteCommand();
        }

    }
}
